use std::process::Command;

use crate::models::models::components::v2ray::basic_setting::ComponentV2rayBasicSetting;
use crate::runtime::error::MagicBoxError;
use crate::runtime::response::Code;
use crate::runtime::result::MagicBoxResult;

/// 查询所有网络服务(MACOS)
#[cfg(target_os = "macos")]
fn get_all_network_services() -> MagicBoxResult<Vec<String>> {
    let networks = Command::new("networksetup").arg("-listallnetworkservices").output();
    if networks.is_err() {
        let err = networks.unwrap_err().to_string();
        log::error!("执行networksetup -listallnetworkservices命令失败: {}", err.as_str());

        return Err(MagicBoxError::new(Code::IoError, format!("获取系统网络配置失败: {}", err.as_str()).as_str()));
    }

    let networks = networks.unwrap();
    if !networks.status.success() {
        log::error!("执行networksetup  -listallnetworkservices命令失败: {}", networks.status.to_string().as_str());

        return Err(MagicBoxError::new(Code::IoError, format!("获取系统网络配置失败: {}", networks.status.to_string().as_str()).as_str()));
    }

    let networks = String::from_utf8(networks.stdout).unwrap();
    if networks.is_empty() {
        return Ok(Vec::new());
    }

    Ok(networks.split("\n").map(|item| item.to_string()).collect::<Vec<String>>())
}

/// 清理系统代理(MACOS)
#[cfg(target_os = "macos")]
pub(crate) fn clear_system_global_proxy() -> MagicBoxResult<()> {
    let networks = get_all_network_services()?;
    for network in networks {
        if network.starts_with("An asterisk") {
            continue;
        }

        let network = network.trim();
        if network.is_empty() {
            continue;
        }

        // http
        let result = Command::new("networksetup").arg("-setwebproxystate").arg(network).arg("off").output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setwebproxystate {} off命令失败: {}", network, err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setwebproxystate {} off命令失败: {}", network, result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }

        // https
        let result = Command::new("networksetup").arg("-setsecurewebproxystate").arg(network).arg("off").output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setsecurewebproxystate {} off命令失败: {}", network, err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setsecurewebproxystate {} off命令失败: {}", network, result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }

        // socks
        let result = Command::new("networksetup").arg("-setsocksfirewallproxystate").arg(network).arg("off").output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setsocksfirewallproxystate {} off命令失败: {}", network, err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setsocksfirewallproxystate {} off命令失败: {}", network, result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("清理系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }
    }

    Ok(())
}

/// 设置系统代理(MACOS)
#[cfg(target_os = "macos")]
pub(crate) fn set_system_global_proxy(setting: &ComponentV2rayBasicSetting) -> MagicBoxResult<()> {
    let networks = get_all_network_services()?;
    for network in networks {
        if network.starts_with("An asterisk") {
            continue;
        }

        let network = network.trim();
        if network.is_empty() {
            continue;
        }

        // http
        let result = Command::new("networksetup").arg("-setwebproxy").arg(network).arg("127.0.0.1").arg(setting.http_port.to_string()).output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setwebproxy {} 127.0.0.1 {}命令失败: {}", network, setting.http_port.to_string(), err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setwebproxy {} 127.0.0.1 {}命令失败: {}", network, setting.http_port.to_string(), result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }

        // https
        let result = Command::new("networksetup").arg("-setsecurewebproxy").arg(network).arg("127.0.0.1").arg(setting.http_port.to_string()).output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setsecurewebproxy {} 127.0.0.1 {}命令失败: {}", network, setting.http_port.to_string(), err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setsecurewebproxy {} 127.0.0.1 {}命令失败: {}", network, setting.http_port.to_string(), result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }

        // socks
        let result = Command::new("networksetup").arg("-setsocksfirewallproxy").arg(network).arg("127.0.0.1").arg(setting.socket_port.to_string()).output();
        if result.is_err() {
            let err = result.unwrap_err().to_string();
            log::error!("执行networksetup -setsocksfirewallproxy {} 127.0.0.1 {}命令失败: {}", network, setting.socket_port.to_string(), err.as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", err.as_str()).as_str()));
        }

        let result = result.unwrap();
        if !result.status.success() {
            log::error!("执行networksetup -setsocksfirewallproxy {} 127.0.0.1 {}命令失败: {}", network, setting.socket_port.to_string(), result.status.to_string().as_str());

            return Err(MagicBoxError::new(Code::IoError, format!("设置系统代理配置失败: {}", result.status.to_string().as_str()).as_str()));
        }
    }

    Ok(())
}
